home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / ibmlogo.zip / VGALOGO.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  35KB  |  1,090 lines

  1. PROGRAM VGA_IBM_LOGO;
  2. {$R-}                         { -> program is much faster }
  3. {$L setpal }              { link the set palette routines }
  4.  
  5. {*********************************************************}
  6. {*                                                       *}
  7. {* VGA/MCGA-Demo/Test-program           Version 1.21     *}
  8. {*                                                       *}
  9. {* IBM INTERNAL USE ONLY                                 *}
  10. {*                                                       *}
  11. {* Copyright (c) IBM Corporation 1988                    *}
  12. {* November 1988                                         *}
  13. {*                                                       *}
  14. {* Idea: David A Kerr wrote the program for the          *}
  15. {*       8514/A display in C                             *}
  16. {*                                                       *}
  17. {* Adapted to VGA / MCGA and to Turbo Pascal 4.0:        *}
  18. {*       Christian Michel                                *}
  19. {*       IBM Deutschland GmbH                            *}
  20. {*       BI Berufsausbildung Sindelfingen 1              *}
  21. {*       Adrs : 7032-54    Kst. 5318                     *}
  22. {*       VM-ID : CMICHEL at STUTVM3                      *}
  23. {*                                                       *}
  24. {* IBM logo is a registered trademark. Modification      *}
  25. {* of logo not permitted.                                *}
  26. {* Replacement with other logo allowed.                  *}
  27. {*                                                       *}
  28. {*********************************************************}
  29.  
  30.  
  31. USES DOS,CRT;
  32.  
  33.  
  34. TYPE rgb          = RECORD
  35.                       red,green,blue : BYTE;
  36.                     END;
  37.      vga_table    = ARRAY [0..255] of rgb;
  38.      ega_map_type = ARRAY [0..16] of BYTE;
  39.  
  40.  
  41. VAR palette,old_pal : vga_table;
  42.     ega_map         : ega_map_type;
  43.     draw_color      : BYTE;
  44.     logo_ofs,i,j,
  45.     hour,min,sec,
  46.     hundred,
  47.     old_mode        : WORD;
  48.     wait,little,
  49.     error           : INTEGER;
  50.     key             : CHAR;
  51.     starttime,
  52.     endtime         : LONGINT;
  53.     cmdline         : STRING;
  54.     directstart,
  55.     check_time,
  56.     frozen,
  57.     slowdown        : BOOLEAN;
  58.  
  59. { Explanation of important variables                       }
  60. {   palette    : color palette for 256 colors              }
  61. {   old_pal    : current palette when starting VGALOGO     }
  62. {   ega_map    : current EGA mapping when starting VGALOGO }
  63. {   draw_color : color to draw the big logo                }
  64. {   logo_ofs   : x,y offset to draw big logo (used for 3-D)}
  65. {   hour,min,                                              }
  66. {   sec,hundred: time got with GETTIME                     }
  67. {   old_mode   : video mode when starting VGALOGO          }
  68. {   wait       : delay of color sweep                      }
  69. {   little     : way the little logos are scrolled through }
  70. {   starttime  : time in seconds                           }
  71. {   endtime    : time in seconds                           }
  72. {   cmdline    : string with single parameter              }
  73. {   check_time : end time is only checked when TRUE        }
  74. {   frozen     : indicates that the palette was frozen     }
  75. {                at the beginning of the program           }
  76. {   slowdown   : indicates slow machines (palette change)  }
  77.  
  78.  
  79.  
  80. PROCEDURE check_vga;
  81.  
  82. { Check the presence of the VGA/MCGA - graphics adapter    }
  83.  
  84.   VAR reg : REGISTERS;
  85.  
  86.   BEGIN { check_vga }
  87.     reg.AX := $1a00;  { read display combination code }
  88.     INTR ($10,reg);
  89.  
  90. { on exit:                                                 }
  91. {    AL = 1Ah -> function 1Ah supported by BIOS            }
  92. {    BL = 7,8 VGA mono / color                             }
  93. {    BL = 11,12 MCGA mono / color                          }
  94.  
  95.     IF (reg.AL<>$1a) OR NOT (reg.BL in [7,8,11,12]) THEN
  96.       BEGIN
  97.         WRITELN (#7,'Sorry, the program needs a VGA or MCGA.');
  98.         HALT;
  99.       END;
  100.   END; { check_vga }
  101.  
  102.  
  103.  
  104. PROCEDURE save_old_video_state;
  105.  
  106. { get the old palette and the current video mode           }
  107.  
  108.   VAR reg : REGISTERS;
  109.  
  110.   BEGIN { save_old_video_state }
  111.  
  112. { first get the old video mode                             }
  113.     reg.AH := $0f;
  114.     INTR ($10,reg);
  115.     old_mode := reg.AL;
  116.  
  117. { then get the old VGA palette                             }
  118.     WITH reg DO
  119.       BEGIN
  120.         AX := $1017;              { read palette registers }
  121.         BX := 0;                  { starting color         }
  122.         CX := 256;                { how many colors        }
  123.         ES := SEG (old_pal);      { load adress of old_pal }
  124.         DX := OFS (old_pal);      { to ES:DX               }
  125.       END;
  126.     INTR ($10,reg);
  127.  
  128. { and now get the old EGA mapping                          }
  129.     WITH reg DO
  130.       BEGIN
  131.         AX := $1009;              { read EGA mapping       }
  132.         ES := SEG (ega_map);      { load adress of ega_map }
  133.         DX := OFS (ega_map);      { to ES:DX               }
  134.       END;
  135.     INTR ($10,reg);
  136.  
  137. { check whether the palette is now frozen or not           }
  138. { check the BIOS-flag at address $0040:$0089 Bit 3         }
  139. {         Bit 3 = 0 -> palette not frozen                  }
  140. {         Bit 3 = 1 -> palette is frozen                   }
  141. { I found this flag by tracing the BIOS-interrupt. So I    }
  142. { can't guarantee that this will be the same with other    }
  143. { BIOS - versions than February 13th, 87.                  }
  144.     frozen := ( MEM [$0040:$0089] AND 8 = 8);
  145.  
  146. { Thaw the palette so that it is changed when switching    }
  147. { video modes. Do this only if palette was frozen.         }
  148.     IF frozen THEN
  149.        BEGIN
  150.          reg.AX := $1200;
  151.          reg.BL := $31;
  152.          INTR ($10,reg);
  153.        END;
  154.  
  155. { finally set the text mode 3 (80 chars/line color)        }
  156.     reg.AX := $03;
  157.     INTR ($10,reg);
  158.   END; { save_old_video_state }
  159.  
  160.  
  161.  
  162. PROCEDURE set_mode_13;
  163.  
  164. { set the graphics mode 13h                                }
  165.  
  166.   VAR reg : REGISTERS;
  167.  
  168.   BEGIN { set_mode_13 }
  169.     reg.AX := $13;
  170.     INTR ($10,reg);
  171.   END; { set_mode_13 }
  172.  
  173.  
  174.  
  175. PROCEDURE restore_old_video_state;
  176.  
  177. { load the old palette,EGA mapping and set old video mode  }
  178.  
  179.   VAR reg : REGISTERS;
  180.  
  181.   BEGIN { restore_old_video_state }
  182.  
  183. { set the old video mode                                   }
  184.     reg.AX := old_mode;
  185.     INTR ($10,reg);
  186.  
  187. { set the old VGA palette                                  }
  188.     WITH reg DO
  189.       BEGIN
  190.         AX := $1012;              { set palette registers  }
  191.         BX := 0;                  { starting color         }
  192.         CX := 256;                { how many colors        }
  193.         ES := SEG (old_pal);      { load adress of old_pal }
  194.         DX := OFS (old_pal);      { to ES:DX               }
  195.       END;
  196.     INTR ($10,reg);
  197.  
  198. { and now set the old EGA mapping                          }
  199.     WITH reg DO
  200.       BEGIN
  201.         AX := $1002;              { write EGA mapping      }
  202.         ES := SEG (ega_map);      { load adress of ega_map }
  203.         DX := OFS (ega_map);      { to ES:DX               }
  204.       END;
  205.     INTR ($10,reg);
  206.  
  207. { Freeze the palette so that it is not changed when        }
  208. { switching video modes. Do this only if the palette was   }
  209. { frozen at the beginning of the program.                  }
  210.     IF frozen THEN
  211.        BEGIN
  212.          reg.AX := $1201;
  213.          reg.BL := $31;
  214.          INTR ($10,reg);
  215.        END;
  216.  
  217.   END; { restore_old_video_state }
  218.  
  219.  
  220.  
  221. PROCEDURE fast_pal (VAR table : vga_table); external;
  222.  
  223.  
  224.  
  225. PROCEDURE slow_pal (VAR table : vga_table); external;
  226.  
  227.  
  228.  
  229. PROCEDURE slow_lower (VAR table : vga_table); external;
  230.  
  231.  
  232.  
  233. PROCEDURE clear_palette;
  234.  
  235.   VAR count : INTEGER;
  236.  
  237.   BEGIN { clear_palette }
  238. { only colors 0 to 106 are used                            }
  239.  
  240.     FOR count := 0 TO 106 DO
  241.       BEGIN
  242.         palette [count].red   := 0;
  243.         palette [count].blue  := 0;
  244.         palette [count].green := 0;
  245.       END;
  246.     slow_pal (palette);
  247.   END; { clear_palette }
  248.  
  249.  
  250.  
  251. PROCEDURE init_palette;
  252.  
  253.   VAR count : INTEGER;
  254.  
  255.   BEGIN { init_palette }
  256. { information about the use of the color numbers :         }
  257. {     0       : background                                 }
  258. {     1-56    : sweeping colors of big logo                }
  259. {     57-101  : sweeping colors of little logos            }
  260. {     102     : static color of little logos               }
  261. {     103-106 : 3-D effect of big logo                     }
  262.  
  263. { colors of big logo and background are all blue           }
  264.  
  265.     FOR count := 0 TO 56 DO
  266.       BEGIN
  267.         palette [count].red   :=0;
  268.         palette [count].blue  :=24;
  269.         palette [count].green :=0;
  270.       END;
  271.  
  272. { colors of little logos are all black                     }
  273.  
  274.     FOR count := 57 TO 101 DO
  275.       BEGIN
  276.         palette [count].red   :=0;
  277.         palette [count].blue  :=0;
  278.         palette [count].green :=0;
  279.       END;
  280.  
  281. { set colors to give the 3-D effect to the big logo        }
  282.  
  283.     FOR count := 103 TO 106 DO
  284.       BEGIN
  285.         palette [count].red   :=0;
  286.         palette [count].blue  :=24;
  287.         palette [count].green :=0;
  288.       END;
  289.     palette [103].green := 28;
  290.     palette [104].green := 26;
  291.     palette [105].green := 24;
  292.     palette [106].green := 22;
  293.  
  294.     slow_pal (palette);
  295.   END; { init_palette }
  296.  
  297.  
  298.  
  299. PROCEDURE plot_w_t (x,y : WORD; color : BYTE);
  300.  
  301. { Plot a pixel only if it isn't already set                }
  302.  
  303.   VAR offset : WORD;
  304.  
  305.   BEGIN { plot_w_t }
  306.      offset := x + 320*y;
  307.      IF MEM [$a000:offset]=0 THEN MEM [$a000:offset] := color;
  308.   END; { plot_w_t }
  309.  
  310.  
  311.  
  312. PROCEDURE draw (x0,y0,x1,y1 : WORD; color : BYTE);
  313.  
  314. { Draw a line                                              }
  315.  
  316.   VAR dx,dy,
  317.       dsum,
  318.       count,help : WORD;
  319.       ix,iy,
  320.       ax,ay   : INTEGER;
  321.  
  322.   BEGIN { draw }
  323.     ay := 0;      ax := 0;
  324.     IF x1>=x0 THEN
  325.       BEGIN
  326.         dx := x1 - x0;   ix := 1;
  327.       END
  328.      ELSE
  329.       BEGIN
  330.         dx := x0 - x1;   ix := -1;
  331.       END;
  332.     IF y1>=y0 THEN
  333.       BEGIN
  334.         dy := y1 - y0;   iy := 1;
  335.       END
  336.      ELSE
  337.       BEGIN
  338.         dy := y0 - y1;   iy := -1;
  339.       END;
  340.     IF dx < dy THEN
  341.       BEGIN
  342.         help := dx;   dx := dy;    dy := help;
  343.         ay := ix;     ax := iy;    ix := 0;    iy := 0;
  344.       END;
  345.     dsum := dx DIV 2;  count := 1;
  346.     plot_w_t (x0,y0,color);
  347.     WHILE count <= dx DO
  348.       BEGIN
  349.         x0 := x0 + ix;   y0 := y0 + ax;   INC (count);
  350.         dsum := dsum + dy;
  351.         IF dsum > dx THEN
  352.           BEGIN
  353.             dsum := dsum - dx;  x0 := x0 + ay;  y0 := y0 + iy;
  354.           END;
  355.         plot_w_t (x0,y0,color);
  356.       END;
  357.   END; { draw }
  358.  
  359.  
  360.  
  361. PROCEDURE fill (x,y : WORD; color : BYTE);
  362.  
  363. { fill any box, y-top line to fill, x-any point within the }
  364. { box that is to be filled                                 }
  365.  
  366.  VAR offset : WORD;
  367.  
  368.  PROCEDURE fill_one_line;
  369.  
  370.    VAR lmargin,          { left margin of line to fill     }
  371.        rmargin,          { right margin of line to fill    }
  372.        carry    : WORD;  { carry bit when calculating the  }
  373.                          { mid point between lmargin and   }
  374.                          { rmargin                         }
  375.  
  376.    BEGIN { fill_one_line }
  377.      MEM [$a000:offset] := color; { set the starting pixel }
  378.  
  379.      lmargin := offset-1;
  380.      WHILE MEM [$a000:lmargin] = 0 DO
  381.        BEGIN { fill to left margin of the box }
  382.        MEM [$a000:lmargin] := color;
  383.        DEC (lmargin);
  384.        END;
  385.  
  386.      rmargin := offset+1;
  387.      WHILE MEM [$a000:rmargin] = 0 DO
  388.        BEGIN { fill to right margin of the box }
  389.        MEM [$a000:rmargin] := color;
  390.        INC (rmargin);
  391.        END;
  392.  
  393.      carry := rmargin AND lmargin AND 1;
  394.      offset := lmargin SHR 1 + rmargin SHR 1 + carry;
  395.    END; { fill_one_line }
  396.  
  397.  BEGIN { fill }
  398.    offset := y*320 +x;
  399.    WHILE MEM [$a000:offset]=0 DO { if color<>0 -> bottom   }
  400.      BEGIN                       { line is reached         }
  401.        fill_one_line;
  402.        INC (offset,320);
  403.      END;
  404.  END;  { fill }
  405.  
  406.  
  407.  
  408. PROCEDURE linex (x1,x2,y : WORD; color : BYTE);
  409.  
  410. { draw a horizontal line                                   }
  411.  
  412.   VAR offset,help : WORD;
  413.  
  414.   BEGIN { linex }
  415.     IF x1>x2 THEN
  416.       BEGIN
  417.         help := x1;
  418.         x1 := x2;
  419.         x2 := help;
  420.       END;
  421.     offset := x1 + 320*y;
  422.     REPEAT
  423.       IF MEM [$a000:offset]=0 THEN MEM [$a000:offset] := color;
  424.       INC (x1); INC (offset);
  425.     UNTIL x1 > x2;
  426.   END; { linex }
  427.  
  428.  
  429.  
  430. PROCEDURE liney (x,y1,y2 : WORD; color : BYTE);
  431.  
  432. { draw a vertical line                                     }
  433.  
  434.   VAR offset,help : WORD;
  435.  
  436.   BEGIN { liney }
  437.     IF y1>y2 THEN
  438.       BEGIN
  439.         help := y1;
  440.         y1 := y2;
  441.         y2 := help;
  442.       END;
  443.     offset := x +320*y1;
  444.     REPEAT
  445.       IF MEM [$a000:offset]=0 THEN MEM [$a000:offset] := color;
  446.       INC (y1); INC (offset,320);
  447.     UNTIL y1 > y2;
  448.   END; { liney }
  449.  
  450.  
  451.  
  452. PROCEDURE t_box (x1,y1,x2 : WORD; color : BYTE);
  453.  
  454.   BEGIN { t_box }
  455.     linex (x1+logo_ofs,x2+logo_ofs,y1+logo_ofs,color);
  456.     liney (x2+logo_ofs,y1+logo_ofs,y1+6+logo_ofs,color);
  457.     linex (x2+logo_ofs,x1+logo_ofs,y1+6+logo_ofs,color);
  458.     liney (x1+logo_ofs,y1+logo_ofs,y1+6+logo_ofs,color);
  459.     fill (x1+logo_ofs+1,y1+logo_ofs+1,color);
  460.   END; { t_box }
  461.  
  462.  
  463.  
  464. PROCEDURE t_box2 (x1,y1,x2,x3,x4 : WORD; color : BYTE);
  465.  
  466.   BEGIN { t_box2 }
  467.     linex (x1+logo_ofs,x2+logo_ofs,y1+logo_ofs,color);
  468.     draw (x2+logo_ofs,y1+logo_ofs,x3+logo_ofs,y1+6+logo_ofs,color);
  469.     linex (x3+logo_ofs,x4+logo_ofs,y1+6+logo_ofs,color);
  470.     draw (x4+logo_ofs,y1+6+logo_ofs,x1+logo_ofs,y1+logo_ofs,color);
  471.     fill (x1+logo_ofs+2,y1+logo_ofs+1,color);
  472.   END; { t_box2 }
  473.  
  474.  
  475.  
  476. PROCEDURE t_box5 (x1,y1,x2,x3,x4,x5 : WORD; color : BYTE);
  477.  
  478.   BEGIN { t_box5 }
  479.     linex (x1+logo_ofs,x2+logo_ofs,y1+logo_ofs,color);
  480.     draw (x2+logo_ofs,y1+logo_ofs,x3+logo_ofs,y1+2+logo_ofs,color);
  481.     draw (x3+logo_ofs,y1+2+logo_ofs,x4+logo_ofs,y1+4+logo_ofs,color);
  482.     draw (x4+logo_ofs,y1+4+logo_ofs,x5+logo_ofs,y1+6+logo_ofs,color);
  483.     linex (x5+logo_ofs,x1+logo_ofs,y1+6+logo_ofs,color);
  484.     liney (x1+logo_ofs,y1+logo_ofs,y1+6+logo_ofs,color);
  485.     fill (x1+logo_ofs+1,y1+logo_ofs+1,color);
  486.   END; { t_box5 }
  487.  
  488.  
  489.  
  490. PROCEDURE t_box7 (x1,y1,x2,x3,x4,x5,x6,x7,x8 : WORD;
  491.                   color : BYTE);
  492.  
  493.   BEGIN { t_box7 }
  494.     linex (x1+logo_ofs,x2+logo_ofs,y1+logo_ofs,color);
  495.     draw (x2+logo_ofs,y1+logo_ofs,x3+logo_ofs,y1+1+logo_ofs,color);
  496.     draw (x3+logo_ofs,y1+1+logo_ofs,x4+logo_ofs,y1+2+logo_ofs,color);
  497.     draw (x4+logo_ofs,y1+2+logo_ofs,x5+logo_ofs,y1+3+logo_ofs,color);
  498.     draw (x5+logo_ofs,y1+3+logo_ofs,x6+logo_ofs,y1+4+logo_ofs,color);
  499.     draw (x6+logo_ofs,y1+4+logo_ofs,x7+logo_ofs,y1+5+logo_ofs,color);
  500.     draw (x7+logo_ofs,y1+5+logo_ofs,x8+logo_ofs,y1+6+logo_ofs,color);
  501.     linex (x8+logo_ofs,x1+logo_ofs,y1+6+logo_ofs,color);
  502.     liney (x1+logo_ofs,y1+logo_ofs,y1+6+logo_ofs,color);
  503.     fill (x1+logo_ofs+1,y1+logo_ofs+1,color);
  504.   END; { t_box7 }
  505.  
  506.  
  507.  
  508. PROCEDURE logo_IBM (color : BYTE);
  509.  
  510. { draw big logo with color                                 }
  511.  
  512.   BEGIN { logo_IBM }
  513.  
  514.     { Letter I }
  515.     t_box (15,51,62,color);
  516.     t_box (15,64,62,color);
  517.     t_box (27,77,50,color);
  518.     t_box (27,90,50,color);
  519.     t_box (27,103,50,color);
  520.     t_box (27,116,50,color);
  521.     t_box (15,129,62,color);
  522.     t_box (15,142,62,color);
  523.  
  524.     { Letter B }
  525.     t_box7 (78,51,133,138,141,143,145,147,149,color);
  526.     t_box5 (78,64,157,159,160,161,color);
  527.     t_box (90,77,113,color);     t_box5 (136,77,162,162,161,160,color);
  528.     t_box7 (90,90,155,154,153,152,150,147,143,color);
  529.     t_box7 (90,103,143,147,149,150,152,154,155,color);
  530.     t_box (90,116,113,color);    t_box5 (136,116,160,161,162,162,color);
  531.     t_box5 (78,129,161,160,159,157,color);
  532.     t_box7 (78,142,149,148,147,145,143,138,133,color);
  533.  
  534.     { Letter M }
  535.     t_box2 (177,51,215,218,177,color);    t_box2 (259,51,297,297,256,color);
  536.     t_box2 (177,64,221,224,177,color);    t_box2 (253,64,297,297,250,color);
  537.     t_box2 (189,77,227,230,189,color);    t_box2 (247,77,285,285,244,color);
  538.     t_box2 (189,90,233,236,189,color);    t_box2 (241,90,285,285,238,color);
  539.     t_box (189,103,212,color);            t_box2 (215,103,259,256,218,color);
  540.     t_box (262,103,285,color);
  541.     t_box (189,116,212,color);            t_box2 (221,116,253,250,224,color);
  542.     t_box (262,116,285,color);
  543.     t_box (177,129,212,color);            t_box2 (227,129,247,244,230,color);
  544.     t_box (262,129,297,color);
  545.     t_box (177,142,212,color);            t_box2 (233,142,241,238,236,color);
  546.     t_box (262,142,297,color);
  547.  
  548.   END; { logo_IBM }
  549.  
  550.  
  551.  
  552. PROCEDURE shade_logo;
  553.  
  554. { shade the 8 bars of the logo with total 56 colors        }
  555.  
  556.   VAR count1,count2,
  557.       col,offset     : WORD;
  558.       color          : BYTE;
  559.  
  560. { Explanation of used variables                            }
  561. {   count1 : counts the bar number (0-7)                   }
  562. {   count2 : counts the screen lines of one bar (0-6)      }
  563. {   col    : x-coordinates of the big logo (15-297)        }
  564. {   offset : memory address of pixel                       }
  565. {   color  : color of each bar-line (1-56)                 }
  566.  
  567. { the color in the line is only changed when the pixel has }
  568. { color 102, each different color isn't of big logo        }
  569.  
  570.   BEGIN { shade_logo }
  571.     color := 1;
  572.     FOR count1 := 0 TO 7 DO              { 8 bars          }
  573.       FOR count2 := 0 TO 6 DO            { 7 shades / bar  }
  574.         BEGIN
  575.           offset := (count1*13 + count2 + 51)*320;
  576.           FOR col := 15 TO 297 DO        { columns of logo }
  577.             IF MEM [$a000:offset+col] = 102 THEN
  578.                MEM [$a000:offset+col] := color;
  579.           INC (color);
  580.         END;
  581.   END; { shade_logo }
  582.  
  583.  
  584.  
  585. PROCEDURE little_logo (x,y : WORD);
  586.  
  587. { draw little logo at position x,y with color 102          }
  588.  
  589.   BEGIN { little_logo }
  590.  
  591.     { Letter I }
  592.     linex (0+x,6+x,0+y,102);
  593.     linex (0+x,6+x,2+y,102);
  594.     linex (2+x,4+x,4+y,102);
  595.     linex (2+x,4+x,6+y,102);
  596.     linex (2+x,4+x,8+y,102);
  597.     linex (2+x,4+x,10+y,102);
  598.     linex (0+x,6+x,12+y,102);
  599.     linex (0+x,6+x,14+y,102);
  600.  
  601.     { Letter B }
  602.     linex (11+x,20+x,0+y,102);
  603.     linex (11+x,22+x,2+y,102);
  604.     linex (13+x,15+x,4+y,102);    linex (20+x,22+x,4+y,102);
  605.     linex (13+x,21+x,6+y,102);
  606.     linex (13+x,21+x,8+y,102);
  607.     linex (13+x,15+x,10+y,102);   linex (20+x,22+x,10+y,102);
  608.     linex (11+x,22+x,12+y,102);
  609.     linex (11+x,20+x,14+y,102);
  610.  
  611.     { Letter M }
  612.     linex (26+x,31+x,0+y,102);    linex (39+x,44+x,0+y,102);
  613.     linex (26+x,32+x,2+y,102);    linex (38+x,44+x,2+y,102);
  614.     linex (28+x,33+x,4+y,102);    linex (37+x,42+x,4+y,102);
  615.     linex (28+x,34+x,6+y,102);    linex (36+x,42+x,6+y,102);
  616.     linex (28+x,30+x,8+y,102);    linex (32+x,38+x,8+y,102);
  617.     linex (40+x,42+x,8+y,102);
  618.     linex (28+x,30+x,10+y,102);   linex (33+x,37+x,10+y,102);
  619.     linex (40+x,42+x,10+y,102);
  620.     linex (26+x,30+x,12+y,102);   linex (34+x,36+x,12+y,102);
  621.     linex (40+x,44+x,12+y,102);
  622.     linex (26+x,30+x,14+y,102);   plot_w_t (35+x,14+y,102);
  623.     linex (40+x,44+x,14+y,102);
  624.  
  625.   END; { little_logo }
  626.  
  627.  
  628.  
  629. PROCEDURE shade_little (choice : INTEGER);
  630.  
  631.   VAR count1,
  632.       col,row,
  633.       offset   : WORD;
  634.       color    : BYTE;
  635.  
  636. { Explanation of variables                                 }
  637. {   count1 : horizontal count of the little logos          }
  638. {   col    : columns of little logos (0-44)                }
  639. {   row    : rows of screen (logos are in rows 4-193)      }
  640. {   offset : memory address of pixel                       }
  641. {   color  : actual color to set the pixel (range 57-101)  }
  642.  
  643. { color is only changed if it has the value 102, other     }
  644. { values don't belong to the little logos                  }
  645.  
  646.   BEGIN { shade_little }
  647.     CASE choice OF
  648.  
  649. { colors are scrolled from left to right in all logos      }
  650.     1: BEGIN
  651.         FOR count1 := 0 TO 5 DO
  652.           BEGIN
  653.             color := 57;
  654.             FOR col := 0 TO 44 DO
  655.               BEGIN
  656.                 FOR row := 4 TO 193 DO
  657.                   BEGIN
  658.                     offset := count1*52 + 7 + row*320;
  659.                     IF MEM [$a000:offset+col] = 102 THEN
  660.                        MEM [$a000:offset+col] :=color;
  661.                   END;
  662.                 INC (color);
  663.               END;
  664.           END;
  665.        END;
  666.  
  667. { colors are scrolled to the center of the screen          }
  668.     2: BEGIN
  669.         FOR count1 := 0 TO 2 DO
  670.           BEGIN
  671.             color := 57;
  672.             FOR col := 0 TO 44 DO
  673.               BEGIN
  674.                 FOR row := 4 TO 193 DO
  675.                   BEGIN
  676.                     offset := count1*52 + 7 + row*320;
  677.                     IF MEM [$a000:offset+col] = 102 THEN
  678.                        MEM [$a000:offset+col] :=color;
  679.                     IF MEM [$a000:offset-col+200] = 102 THEN
  680.                        MEM [$a000:offset-col+200] :=color;
  681.                   END;
  682.                 INC (color);
  683.               END;
  684.           END;
  685.        END;
  686.  
  687. { colors are scrolled from center to outside               }
  688.     3: BEGIN
  689.         FOR count1 := 0 TO 2 DO
  690.           BEGIN
  691.             color := 101;
  692.             FOR col := 0 TO 44 DO
  693.               BEGIN
  694.                 FOR row := 4 TO 193 DO
  695.                   BEGIN
  696.                     offset := count1*52 + 7 + row*320;
  697.                     IF MEM [$a000:offset+col] = 102 THEN
  698.                        MEM [$a000:offset+col] :=color;
  699.                     IF MEM [$a000:offset-col+200] = 102 THEN
  700.                        MEM [$a000:offset-col+200] :=color;
  701.                   END;
  702.                 DEC (color);
  703.               END;
  704.           END;
  705.        END;
  706.  
  707. { all little logos are black                               }
  708.     4: BEGIN
  709.         palette [102].red   := 0;
  710.         palette [102].green := 0;
  711.         palette [102].blue  := 0;
  712.        END;
  713.  
  714. { all little logos are white                               }
  715.     5: BEGIN
  716.         palette [102].red   := 45;
  717.         palette [102].green := 45;
  718.         palette [102].blue  := 45;
  719.        END;
  720.  
  721. { colors are scrolled from left to right in all logos      }
  722. { shade goes about the whole screen                        }
  723.     6: BEGIN
  724.         color := 57;
  725.         FOR count1 := 0 TO 5 DO
  726.           BEGIN
  727.             col := 0;
  728.             WHILE col <= 44 DO
  729.               BEGIN
  730.                 FOR row := 4 TO 193 DO
  731.                   BEGIN
  732.                     offset := count1*52 + 7 + row*320;
  733.                     IF MEM [$a000:offset+col] = 102 THEN
  734.                        MEM [$a000:offset+col] :=color;
  735.                   END;
  736.                 INC (col);
  737.                 IF (col DIV 6)*6 = col THEN INC (color);
  738.               END;
  739.           END;
  740.        END;
  741.  
  742. { colors are scrolled from outside to center in all logos  }
  743. { shade goes about the whole screen                        }
  744.     7: BEGIN
  745.         color := 57;
  746.         FOR count1 := 0 TO 2 DO
  747.           BEGIN
  748.             col := 0;
  749.             WHILE col <= 44 DO
  750.               BEGIN
  751.                 FOR row := 4 TO 193 DO
  752.                   BEGIN
  753.                     offset := count1*52 + 7 + row*320;
  754.                     IF MEM [$a000:offset+col] = 102 THEN
  755.                        MEM [$a000:offset+col] :=color;
  756.                     offset := 5*52 + 51 + row*320 - count1*52 -col;
  757.                     IF MEM [$a000:offset] = 102 THEN
  758.                        MEM [$a000:offset] :=color;
  759.                   END;
  760.                 INC (col);
  761.                 IF (col DIV 3)*3 = col THEN INC (color);
  762.               END;
  763.           END;
  764.        END;
  765.  
  766. { colors are scrolled from outside to center in all logos  }
  767. { shade goes about the whole screen                        }
  768.     8: BEGIN
  769.         color := 101;
  770.         FOR count1 := 0 TO 2 DO
  771.           BEGIN
  772.             col := 0;
  773.             WHILE col <= 44 DO
  774.               BEGIN
  775.                 FOR row := 4 TO 193 DO
  776.                   BEGIN
  777.                     offset := count1*52 + 7 + row*320;
  778.                     IF MEM [$a000:offset+col] = 102 THEN
  779.                        MEM [$a000:offset+col] :=color;
  780.                     offset := 5*52 + 51 + row*320 - count1*52 -col;
  781.                     IF MEM [$a000:offset] = 102 THEN
  782.                        MEM [$a000:offset] :=color;
  783.                   END;
  784.                 INC (col);
  785.                 IF (col DIV 3)*3 = col THEN DEC (color);
  786.               END;
  787.           END;
  788.        END;
  789.  
  790.     END; { of CASE choice }
  791.   END; { shade_little }
  792.  
  793.  
  794.  
  795. PROCEDURE play_with_palette (r,g,b : INTEGER);
  796.  
  797.   VAR i,j,max : INTEGER;
  798.       static  : BOOLEAN;  { colors of little logo are
  799.                             static if true }
  800.  
  801.   BEGIN { play_with_palette }
  802.  
  803.     static := little in [0,4,5];
  804.     IF (r+g+b=3) AND static THEN max := 127
  805.        ELSE max := 255;
  806.  
  807.     FOR j := 0 TO max DO
  808.       BEGIN
  809.  
  810. { check ESC - key                                          }
  811.         IF KEYPRESSED THEN
  812.           BEGIN
  813.             key := READKEY;
  814.             IF key = CHR (27) THEN
  815.               BEGIN
  816.                 restore_old_video_state;
  817.                 HALT;
  818.               END;
  819.           END;
  820.  
  821. { check for stop time if needed                            }
  822.         IF check_time THEN
  823.            BEGIN
  824.              GETTIME (hour,min,sec,hundred);
  825.              IF hour*3600 + min*60 + sec > endtime THEN
  826.                 BEGIN
  827.                   restore_old_video_state;
  828.                   HALT;
  829.                 END;
  830.            END;
  831.  
  832. { shift palette up one (big logo)                          }
  833.         FOR i:= 56 DOWNTO 2 DO palette[i] := palette[i-1];
  834.  
  835. { shift palette up one (little logos)                      }
  836.         FOR i := 101 DOWNTO 58 DO palette[i] := palette[i-1];
  837.  
  838.         IF j<64 THEN
  839.           BEGIN
  840.             IF (r=1) AND (palette[1].red<63) THEN
  841.                 INC (palette[1].red);
  842.             IF (g=1) AND (palette[1].green<63) THEN
  843.                 INC (palette[1].green);
  844.             IF (b=1) AND (palette[1].blue<63) THEN
  845.                 INC (palette[1].blue);
  846.             IF (r=0) AND (palette[57].red<63) THEN
  847.                 INC (palette[57].red);
  848.             IF (g=0) AND (palette[57].green<63) THEN
  849.                 INC (palette[57].green);
  850.             IF (b=0) AND (palette[57].blue<63) THEN
  851.                 INC (palette[57].blue);
  852.           END
  853.           ELSE IF j < 128 THEN
  854.             BEGIN
  855.               IF (r=1) AND (palette[1].red>0) THEN
  856.                 DEC (palette[1].red);
  857.               IF (g=1) AND (palette[1].green>0) THEN
  858.                 DEC (palette[1].green);
  859.               IF (b=1) AND (palette[1].blue>24) THEN
  860.                 DEC (palette[1].blue);
  861.               IF (r=0) AND (palette[57].red>0) THEN
  862.                  DEC (palette[57].red);
  863.               IF (g=0) AND (palette[57].green>0) THEN
  864.                  DEC (palette[57].green);
  865.               IF (b=0) AND (palette[57].blue>0) THEN
  866.                  DEC (palette[57].blue);
  867.             END
  868.            ELSE IF j<196 THEN
  869.              BEGIN
  870.                IF (r=0) AND (palette[1].red<63) THEN
  871.                  INC (palette[1].red);
  872.                IF (g=0) AND (palette[1].green<63) THEN
  873.                  INC (palette[1].green);
  874.                IF (b=0) AND (palette[1].blue<63) THEN
  875.                  INC (palette[1].blue);
  876.                IF (r=1) AND (palette[57].red<63) THEN
  877.                  INC (palette[57].red);
  878.                IF (g=1) AND (palette[57].green<63) THEN
  879.                  INC (palette[57].green);
  880.                IF (b=1) AND (palette[57].blue<63) THEN
  881.                  INC (palette[57].blue);
  882.              END
  883.             ELSE
  884.               BEGIN
  885.                 IF (r=0) AND (palette[1].red>0) THEN
  886.                   DEC (palette[1].red);
  887.                 IF (g=0) AND (palette[1].green>0) THEN
  888.                   DEC (palette[1].green);
  889.                 IF (b=0) AND (palette[1].blue>24) THEN
  890.                   DEC (palette[1].blue);
  891.                 IF (r=1) AND (palette[57].red>0) THEN
  892.                   DEC (palette[57].red);
  893.                 IF (g=1) AND (palette[57].green>0) THEN
  894.                   DEC (palette[57].green);
  895.                 IF (b=1) AND (palette[57].blue>0) THEN
  896.                   DEC (palette[57].blue);
  897.               END;
  898.  
  899. { set the palette                                          }
  900. { If the palette change has to be slowed down check        }
  901. { whether only the lower part of the palette has to be     }
  902. { changed (this case occurs, when the little logos have a  }
  903. { static color). Otherwise use the fast routine.           }
  904.  
  905.         IF slowdown THEN
  906.           IF static THEN slow_lower (palette)
  907.              ELSE slow_pal (palette)
  908.           ELSE fast_pal (palette);
  909.  
  910. { wait the so many retraces as given by Wn option          }
  911.         DELAY (16*wait);
  912.      END;
  913.   END; { play_with_palette }
  914.  
  915.  
  916.  
  917. PROCEDURE first_text;
  918.  
  919. BEGIN { first_text }
  920.   CLRSCR;
  921.   TEXTCOLOR (15);
  922.   WRITELN ('                     VGA_IBM_Logo  Version 1.21');
  923.   TEXTCOLOR (7);
  924.   WRITELN;
  925.   WRITELN ('Copyright (c) 1988 IBM Corporation');
  926.   WRITELN;
  927.   WRITELN ('IBM Internal Use Only.');
  928.   WRITELN;
  929.   WRITELN ('by Christian Michel');
  930.   WRITELN ('   IBM Deutschland GmbH, BI Berufsausbildung Sindelfingen');
  931.   WRITELN ('   VM-ID: CMICHEL at STUTVM3');
  932.   WRITELN;
  933.   WRITE   ('This program is a demonstration of the VGA/MCGA ');
  934.   WRITELN ('320 x 200 x 256 colors mode.');
  935.   WRITELN;
  936. END; { first_text }
  937.  
  938.  
  939.  
  940. PROCEDURE help_parameters;
  941.  
  942. BEGIN { help_parameters }
  943.    first_text;
  944.    WRITELN ('Options:  VGALOGO [Ln] [Wn] [D<n>] [S<n>]');
  945.    WRITE   ('          Ln : changes the way the colors ');
  946.    WRITELN ('of the little logos are scrolled');
  947.    WRITE   ('               (0-suppress little logos, 1-');
  948.    WRITELN ('left to right, 2-to center,');
  949.    WRITE   ('                3-to outside, 4-static ');
  950.    WRITELN ('black, 5-static white,');
  951.    WRITE   ('                6..8-same as 1..3 but about ');
  952.    WRITELN ('the whole screen)');
  953.    WRITE   ('          Wn : selects the speed the colors ');
  954.    WRITELN ('are changed (Wait cycles)');
  955.    WRITELN ('               (0 <= n <= 10) ');
  956.    WRITELN ('          D  : skips title screen (Direct start)');
  957.    WRITELN ('          Dn : runs demo for n seconds (Duration)');
  958.    WRITE   ('          S  : Slowdown palette shift to suppress ');
  959.    WRITELN ('snow on slow computers');
  960.    WRITE   ('          Sn : Slowdown mode of palette shift ');
  961.    WRITELN ('(0-don''t slowdown, 1-slowdown)');
  962.    WRITE   ('Default: L1, W0, demo runs until ESC pressed, ');
  963.    WRITE   ('fast palette shift on 80286 models');
  964.    REPEAT UNTIL KEYPRESSED;
  965.    restore_old_video_state;
  966.    HALT;
  967. END; { help_parameters }
  968.  
  969.  
  970.  
  971. BEGIN { main_program }
  972.  
  973. { check presence of required graphics adapter              }
  974.   check_vga;
  975.  
  976. { restore old video state and switch to text mode          }
  977.   save_old_video_state;
  978.  
  979. { check help option                                        }
  980.   IF PARAMCOUNT <> 0 THEN
  981.      IF COPY (PARAMSTR (1),1,1) = '?' THEN help_parameters;
  982.  
  983. { set default for variables                                }
  984.   wait := 0; little := 1; endtime := MAXLONGINT;
  985.   directstart := FALSE; check_time := FALSE;
  986.  
  987.   GETTIME (hour,min,sec,hundred);
  988.   starttime := hour*3600 + min*60 + sec;
  989.  
  990. { set the slowdown flag dependent on the computer-model    }
  991.   IF MEM [$f000:$fffe] = $fc THEN slowdown := FALSE
  992.     ELSE slowdown := TRUE;
  993. { $fc stands for: PC/AT, PC/XT 286, PS/2 Model 50,60,70,80 }
  994.  
  995. { parse the commandline options                            }
  996.   IF PARAMCOUNT <> 0 THEN
  997.     FOR i:= 1 TO PARAMCOUNT DO
  998.       BEGIN
  999.         CmdLine := PARAMSTR (i);
  1000.         CASE UPCASE (CmdLine[1]) of
  1001.           'L': BEGIN
  1002.                  DELETE (CmdLine,1,1);
  1003.                  VAL (CmdLine,j,error);
  1004.                  IF error = 0 THEN little := j;
  1005.                END;
  1006.           'W': BEGIN
  1007.                  DELETE (CmdLine,1,1);
  1008.                  VAL (CmdLine,j,error);
  1009.                  IF error = 0 THEN wait := j;
  1010.                END;
  1011.           'S': BEGIN
  1012.                  DELETE (CmdLine,1,1);
  1013.                  VAL (CmdLine,j,error);
  1014.                  IF (error = 0) AND (j = 0) THEN
  1015.                      slowdown := FALSE
  1016.                    ELSE slowdown := TRUE;
  1017.                END;
  1018.           'D': BEGIN
  1019.                  DELETE (CmdLine,1,1);
  1020.                  VAL (CmdLine,j,error);
  1021.                  directstart := TRUE;
  1022.                  { don't show the title screen }
  1023.                  IF error = 0 THEN
  1024.                     BEGIN
  1025.                       endtime := starttime + j + 2;
  1026.                       { building up the screen takes about
  1027.                       2 seconds }
  1028.                       check_time := TRUE;
  1029.                     END;
  1030.                END;
  1031.           END; { of case }
  1032.       END; { of for }
  1033.  
  1034. { check for parameter ranges                               }
  1035.  
  1036.   IF NOT (little IN [0..8]) THEN little := 1;
  1037.   IF wait > 10 THEN wait := 0;
  1038.  
  1039.   logo_ofs := 0;
  1040.  
  1041.   IF directstart = FALSE THEN
  1042.     BEGIN
  1043.       first_text;
  1044.       WRITE   ('The program was adapted to VGA/MCGA ');
  1045.       WRITELN ('from the 8514/A-program IBMLOGO written by');
  1046.       WRITELN ('                             David A Kerr.');
  1047.       WRITELN;
  1048.       WRITE   ('The routine to change the palette was ');
  1049.       WRITELN ('delivered from');
  1050.       WRITELN ('        Daniel Butterfield (DAZZLE).');
  1051.       WRITELN;
  1052.       WRITELN ('Press any key to start the program.');
  1053.       WRITELN ('ESC stops execution.');
  1054.       REPEAT UNTIL KEYPRESSED;
  1055.       key := READKEY;
  1056.     END;
  1057.  
  1058.   set_mode_13;
  1059.   clear_palette;
  1060.  
  1061.   logo_IBM (102);
  1062.   shade_logo;
  1063.  
  1064. { give 3-D effect to big logo                              }
  1065.   FOR draw_color := 103 TO 106 DO
  1066.     BEGIN
  1067.       INC (logo_ofs);
  1068.       logo_IBM (draw_color);
  1069.     END;
  1070.  
  1071. { draw little logos only if they're needed                 }
  1072.   IF little <> 0 THEN
  1073.     BEGIN
  1074.       FOR i := 0 TO 7 DO
  1075.         FOR j:= 0 TO 5 DO
  1076.           little_logo (j*52+7,i*25+4);
  1077.       shade_little (little);
  1078.     END;
  1079.  
  1080.   init_palette;
  1081.  
  1082.   REPEAT
  1083.     play_with_palette (1,1,1);
  1084.     play_with_palette (1,0,0);
  1085.     play_with_palette (0,1,0);
  1086.     play_with_palette (0,0,1);
  1087.   UNTIL FALSE;
  1088.  
  1089. END. { main_program }
  1090.